#include <Winsock2.h>
#include <WS2tcpip.h>
#include <iostream>


using std::cout;
using std::cin;
using std::cerr;
using std::endl;

#pragma comment(lib, "ws2_32.lib")

const int MSG_BUF_SIZE = 512;
int SOCKADDR_SIZE = sizeof(SOCKADDR);
const int SERV_PORT = 4000;
//const char* SERV_IP = "127.0.0.1";
PCWSTR SERV_IP = TEXT("127.0.0.1");
//int message_send(SOCKADDR_IN addr_serv, char* message);
//int message_get(SOCKADDR_IN addr_serv,char *msg_buf,int buffer_size);

int main() {
    WSADATA wsa_data;
    SOCKET sock_clt = INVALID_SOCKET;
    SOCKADDR_IN addr_serv;
    char msg_buf[MSG_BUF_SIZE];
    int ret_val = 0;
    //
    ret_val = WSAStartup(MAKEWORD(2, 2), &wsa_data);
    if (ret_val != 0) {
        cerr << "WSAStartup() function failed with error: " << WSAGetLastError() << "\n";
        system("pause");
        return 1;
    }
    //
    sock_clt = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock_clt == INVALID_SOCKET) {
        cerr << "socket() function failed with error: " << WSAGetLastError() << "\n";
        WSACleanup();
        system("pause");
        return 1;
    }
    //
    addr_serv.sin_family = AF_INET;
    addr_serv.sin_port = htons(SERV_PORT);
    ret_val = InetPton(addr_serv.sin_family, SERV_IP, &addr_serv.sin_addr);
    if (ret_val != 1) {
        cerr << "inet_pton() function failed with error: " << WSAGetLastError() << "\n";
        closesocket(sock_clt);
        WSACleanup();
        system("pause");
        return 1;
    }
    //
    cout << "A UDP client has already started successfully..." << endl;
    //
    //SecureZeroMemory(msg_buf, MSG_BUF_SIZE);
    while (true) {
        cout << "enter the message you want to send: ";
        cin.getline(msg_buf, MSG_BUF_SIZE);
        ret_val = sendto(sock_clt, msg_buf, strlen(msg_buf), 0, (SOCKADDR*)&addr_serv, SOCKADDR_SIZE);
        if (ret_val == SOCKET_ERROR) {
            cerr << "sendto() function failed with error: " << WSAGetLastError() << "\n";
            closesocket(sock_clt);
            WSACleanup();
            system("pause");
            return 1;
        }
        SecureZeroMemory(msg_buf, MSG_BUF_SIZE);
        ret_val = recvfrom(sock_clt, msg_buf, MSG_BUF_SIZE, 0, (SOCKADDR*)&addr_serv, &SOCKADDR_SIZE);
        if (ret_val > 0) {
            cout << "feedback from the server: " << msg_buf << endl;
        }
        else if (ret_val == 0) {
            cout << "connection is closed..." << endl;
        }
        else {
            cerr << "recvfrom() function failed with error: " << WSAGetLastError() << "\n";
            closesocket(sock_clt);
            WSACleanup();
            system("pause");
            return 1;
        }
    }
    ret_val = shutdown(sock_clt, SD_BOTH);
    if (ret_val == SOCKET_ERROR) {
        cerr << "shutdown() function failed with error: " << WSAGetLastError() << "\n";
        closesocket(sock_clt);
        WSACleanup();
        system("pause");
        return 1;
    }
    closesocket(sock_clt);
    WSACleanup();
    system("pause");
    return 0;
}
// int main() {
//     SOCKADDR_IN addr_serv;
//     addr_serv.sin_family = AF_INET;
//     addr_serv.sin_port = htons(SERV_PORT);
//     int ret_val;
//     ret_val = InetPton(addr_serv.sin_family, SERV_IP, &addr_serv.sin_addr);
//     if (ret_val != 1) {
//         cerr << "inet_pton() function failed with error: " << WSAGetLastError() << "\n";
//         system("pause");
//         return 1;
//     }
//     char msg_buf[MSG_BUF_SIZE];
//     char msg2[MSG_BUF_SIZE];
//     cout << "enter the message you want to send:" << endl;
//     cin.getline(msg_buf, MSG_BUF_SIZE);
//     //message_send(addr_serv, msg_buf);
//     //SecureZeroMemory(msg2, MSG_BUF_SIZE);
  
//     message_get(addr_serv,msg2,MSG_BUF_SIZE);
//     return(0);

// }

// int message_send(SOCKADDR_IN addr_serv,char *message) {
//     WSADATA wsa_data;
//     SOCKET sock_clt = INVALID_SOCKET;
//     int ret_val = 0;
//     int socksize=sizeof(SOCKADDR);   

//     ret_val = WSAStartup(MAKEWORD(2, 2), &wsa_data);
//     if (ret_val != 0) {
//         cerr << "WSAStartup() function failed with error: " << WSAGetLastError() << "\n";
//         system("pause");
//         return 1;
//     }
//     sock_clt = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
//     if (sock_clt == INVALID_SOCKET) {
//         cerr << "socket() function failed with error: " << WSAGetLastError() << "\n";
//         WSACleanup();
//         system("pause");
//         return 1;
//     }
//     cout << "A UDP client has already started successfully..." << endl;
//     ret_val = sendto(sock_clt, message, strlen(message), 0, (SOCKADDR*)&addr_serv, socksize);
//     if (ret_val == SOCKET_ERROR) {
//         cerr << "sendto() function failed with error: " << WSAGetLastError() << "\n";
//         closesocket(sock_clt);
//         WSACleanup();
//         system("pause");
//         return 1;
//     }
    /*
    ret_val = recvfrom(sock_clt, message, MSG_BUF_SIZE, 0, (SOCKADDR*)&addr_serv, &SOCKADDR_SIZE);
    if (ret_val > 0) {
        cout << "feedback from the server: " << message << endl;
    }
    else if (ret_val == 0) {
        cout << "connection is closed..." << endl;
    }
    else {
        cerr << "recvfrom() function failed with error: " << WSAGetLastError() << "\n";
        closesocket(sock_clt);
        WSACleanup();
        system("pause");
        return 1;
    }*/
//     ret_val = shutdown(sock_clt, SD_BOTH);
//     if (ret_val == SOCKET_ERROR) {
//         cerr << "shutdown() function failed with error: " << WSAGetLastError() << "\n";
//         closesocket(sock_clt);
//         WSACleanup();
//         system("pause");
//         return 1;
//     }
//     closesocket(sock_clt);
//     WSACleanup();
//     system("pause");
//     return 0;
// }
/*
int message_get(SOCKADDR_IN addr_serv,char *msg_buf,int buffer_size) {
    WSADATA wsa_data;
    SOCKET sock_clt = INVALID_SOCKET;
    int ret_val = 0;
    //int socksize=sizeof(SOCKADDR);

    ret_val = WSAStartup(MAKEWORD(2, 2), &wsa_data);
    if (ret_val != 0) {
        cerr << "WSAStartup() function failed with error: " << WSAGetLastError() << "\n";
        system("pause");
        return 1;
    }
    sock_clt = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock_clt == INVALID_SOCKET) {
        cerr << "socket() function failed with error: " << WSAGetLastError() << "\n";
        WSACleanup();
        system("pause");
        return 1;
    }
    cout << "A UDP client has already started successfully..." << endl;
    ret_val = recvfrom(sock_clt,msg_buf, MSG_BUF_SIZE, 0, (SOCKADDR*)&addr_serv, &SOCKADDR_SIZE);
    if (ret_val > 0) {
        cout << "feedback from the server: " << msg_buf << endl;
    }
    else if (ret_val == 0) {
            cout << "connection is closed..." << endl;
    }
    else {
        cerr << "recvfrom() function failed with error: " << WSAGetLastError() << "\n";
        closesocket(sock_clt);
        WSACleanup();
        system("pause");
        return 1;
    }
    ret_val = shutdown(sock_clt, SD_BOTH);
    if (ret_val == SOCKET_ERROR) {
        cerr << "shutdown() function failed with error: " << WSAGetLastError() << "\n";
        closesocket(sock_clt);
        WSACleanup();
        system("pause");
        return 1;
    }
    closesocket(sock_clt);
    WSACleanup();
    system("pause");
    return 0;
}*/


